/* 
 * File:   OperacionCargaNuevoArchivo.cpp
 * Author: max
 * 
 * Created on May 31, 2013, 12:53 AM
 */

#include <sstream>

#include "client_OperacionCargaNuevoArchivo.h"
using namespace TP::Operaciones;

OperacionCargaNuevoArchivo::OperacionCargaNuevoArchivo(uint32_t pToken, FileServiceProxy* pFileService, Repositorio* pRepositorio, const string &pNombreArchivo) : Operacion(pToken) {
    _fileService = pFileService;
    _repositorio = pRepositorio;
    _nombreArchivo = pNombreArchivo;
}

OperacionCargaNuevoArchivo::~OperacionCargaNuevoArchivo() {
    _fileService = NULL;
    _repositorio = NULL;
}

void OperacionCargaNuevoArchivo::ejecutar(){
    
    // Inicialmente se declara el archivo en el servidor.

    _fileService->DeclareFile(getId(), _nombreArchivo);
}

void OperacionCargaNuevoArchivo::procesarRespuesta (vector<string> &pRespuesta){

    /* Formato de la respuesta:
     * 
     * <token>;<Resultado_operacion>
     * 
     * <token>;<accion>;<resultado>;<args>
     * 
     */
    
    /* Identificar la accion que origino la respuesta.  Los tipos de acciones
     * pueden ser:
     * 
     * 1) Nuevo archivo.
     * 2) Subir chunk.
     * 3) Definir archvo.
     * 
     */ 
    if (FS_DECLARAR_ARCHIVO == pRespuesta[2])
    {
        manejarRespuestaDeclaracionArchivo (pRespuesta);
    }
    else if (FS_PUT_CHUNK == pRespuesta[2])
    {
        manejarRespuestaCargarArchivo(pRespuesta);
    }
    else if (FS_DEFINIR_ARCHIVO == pRespuesta[2])
    {
        manejarRespuestaFinalizarCargaArchivo (pRespuesta);
    }
    else
    {
        cerr << "Respuesta de servicio no reconocida" << pRespuesta[2] << endl;
        this->setFinalizada(true);
    }
}

void OperacionCargaNuevoArchivo::manejarRespuestaDeclaracionArchivo (vector<string> &pRespuesta){

    // <token>;<service>;<method>;<result ejec>;<msg>    
    
    if (FS_OK == pRespuesta[3])
    {
        // Inicio la carga de archivo.
        
        /* chunk dummy a fin de probar la carga de archivos.
         */
        string chunk = "Chunk numero: 1\n";
        
        _fileService->PutFileChunk(getId(), _nombreArchivo, 1, (const uint8_t*)chunk.c_str(), chunk.length());
    }
    else
    {
        // Intento declarar el archivo una vez mas.
        
        setFinalizada(true);
    }
}

void OperacionCargaNuevoArchivo::manejarRespuestaCargarArchivo(vector<string> &pRespuesta){
    
    // <token>;<service>;<method>;<chunk_num>;<ejec result>;<msg>
    
    static uint32_t chunkNumber = 2;

    if (FS_OK == pRespuesta[4])
    {
        // Inicio la carga de archivo.
        
        if (chunkNumber == 10)
        {
            // Se transmitieron 10 chunks. Luego, se finaliza el archivo.
            _fileService->DefineFile(getId(), _nombreArchivo);
            chunkNumber = 2;
        }
        else
        {
            std::stringstream strstm;
            strstm << chunkNumber++;

            string chunk = "Chunk numero: ";
            chunk += strstm.str();

            _fileService->PutFileChunk(getId(), _nombreArchivo, chunkNumber, (const uint8_t*) chunk.c_str(), chunk.length());
        }
    }
    else
    {
        // Intento declarar el archivo nuevamente.
        setFinalizada(true);       
    }    
    
}

void OperacionCargaNuevoArchivo::manejarRespuestaFinalizarCargaArchivo (vector<string> &pRespuesta){
    
    if (FS_OK != pRespuesta[3])
    {
        // Se termina la operacion.
        cout << "error definiendo el archivo." << endl;
    }
    this->setFinalizada(true);
}
